#ifndef _STACKOPERATIONS_H
#define _STACKOPERATIONS_H
#include "stack.h"
#include <math.h>

/*!
 *  \fn mul
 *  \brief pulls two elements, multiplicates them and pushes result back into stack
 *  \param Stack is a pointer to a stack_t variable
 *  \return 0 if operation wasn't successful, 1 otherwise
 */

int mul(struct stack_t* stack);

/*!
 *  \fn sub
 *  \brief pulls two elements, substracts one from another and pushes result back into stack
 *  \param Stack is a pointer to a stack_t variable
 *  \return 0 if operation wasn't successful, 1 otherwise
 */

int sub(struct stack_t* stack);

/*!
 *  \fn add
 *  \brief pulls two elements, adds them and pushes result back into stack
 *  \param Stack is a pointer to a stack_t variable
 *  \return 0 if operation wasn't successful, 1 otherwise
 */
int add(struct stack_t* stack);

/*!
 *  \fn div
 *  \brief pulls two elements, divides one on another and pushes result back into stack
 *  \param Stack is a pointer to a stack_t variable
 *  \return 0 if operation wasn't successful, 1 otherwise
 */

int struct_div(struct stack_t* stack);

/*!
 *  \fn sqr
 *  \brief pulls one element, makes square from in and pushes result back into stack
 *  \param Stack is a pointer to a stack_t variable
 *  \return 0 if operation wasn't successful, 1 otherwise
 */
int sqr(struct stack_t* stack);

/*!
 *  \fn stack_sqrt
 *  \brief pulls one element, takes square root from it and pushes result back into stack
 *  \param Stack is a pointer to a stack_t variable
 *  \return 0 if operation wasn't successful, 1 otherwise
 */
int stack_sqrt(struct stack_t* stack);


int mul(struct stack_t* stack)
{
    double a = 0;
    double b = 0;
    int x = Stack_pop(stack, &a);
    int y = Stack_pop(stack, &b);
    if (x && y)
    {
        double c = a * b;
        Stack_push(stack, c);
        return 1;
    }
    else if (x)
    {
        Stack_push(stack, a);
    }
    return 0;
}

int sub(struct stack_t* stack)
{
    double a = 0;
    double b = 0;
    int x = Stack_pop(stack, &a);
    int y = Stack_pop(stack, &b);
    if(x && y)
    {
        double c = a - b;
        Stack_push(stack, c);
        return 1;
    }
    else if (x)
    {
        Stack_push(stack, a);
    }
    return 0;
}


int add(struct stack_t* stack)
{
    double a = 0;
    double b = 0;
    int x = Stack_pop(stack,&a);
    int y = Stack_pop(stack, &b);
    if(x && y)
    {
        double c = a + b;
        Stack_push(stack, c);
        return 1;
    }
    else if (x)
    {
        Stack_push(stack, a);
    }
    return 0;
}

int struct_div(struct stack_t* stack)
{
    double a = 0;
    double b = 0;
    int x = Stack_pop(stack, &b);
    int y = Stack_pop(stack, &a);
    if((x && y) && b)
    {
        double c = a/b;
        Stack_push(stack, c);
        return 1;
    }
    else if (!b)
    {
        if (x && y)
        {
            Stack_push(stack, b);
            Stack_push(stack, a);
        }
        if (x)
        {
            Stack_push(stack, a);
        }
    }
    else
    {
        if (x)
        {
            Stack_push(stack, a);
        }
    }
    return 0;
}


int sqr(struct stack_t* stack)
{
    double a = 0;
    int x = Stack_pop(stack, &a);
    if(x)
    {
        double c = a*a;
        Stack_push(stack, c);
        return 1;
    }
    return 0;
}

int stack_sqrt(struct stack_t* stack)
{
    double a = 0;
    int x = Stack_pop(stack, &a);
    if(x && a >= 0)
    {
        double c = sqrt(a);
        Stack_push(stack, c);
        return 1;
    }
    else if (x)
    {
        Stack_push(stack, a);
    }
    return 0;
}


#endif // _STACKOPERATIONS_H
